﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

// The User Control item template is documented at http://go.microsoft.com/fwlink/?LinkId=234236

namespace Windows8DatePicker
{
    public sealed partial class DatePicker : UserControl
    {
        private DateTime _datetime;
        private int _width = 7;
        private int _height = 6;
        private Button[,] buttonGrid = new Button[6, 7];

        private Boolean _showTimePicker = true;
        public Boolean showTimePicker
        {
            get { return _showTimePicker; }
            set
            {
                if (value)
                    StackPanelTimePicker.Visibility = Visibility.Visible;
                else
                    StackPanelTimePicker.Visibility = Visibility.Collapsed;

                _showTimePicker = value;
            }
        }

        public DatePicker()
        {
            this.InitializeComponent();
            setupButtons();
            setupListViews();
            setDateTime(DateTime.Now, true, true);
        }

        public DatePicker(DateTime datetime, Boolean showTimePicker, Boolean showCalendar)
        {
            this.InitializeComponent();
            setupButtons();
            setupListViews();
            setDateTime(datetime, showTimePicker, showCalendar);
        }

        public DateTime getDateTime()
        {
            return _datetime;
        }

        public void setDateTime(DateTime datetime, Boolean showTimePicker, Boolean showCalendar)
        {
            _datetime = datetime;
            loadMonth();
            setupListViews();

            if (!showTimePicker)
                StackPanelTimePicker.Visibility = Visibility.Collapsed;
            else
                StackPanelTimePicker.Visibility = Visibility.Visible;

            if (!showCalendar)
                StackPanelCalendarPicker.Visibility = Visibility.Collapsed;
            else
                StackPanelCalendarPicker.Visibility = Visibility.Visible;
        }

        private void setupButtons()
        {

            buttonGrid[0, 0] = B00;
            buttonGrid[0, 1] = B01;
            buttonGrid[0, 2] = B02;
            buttonGrid[0, 3] = B03;
            buttonGrid[0, 4] = B04;
            buttonGrid[0, 5] = B05;
            buttonGrid[0, 6] = B06;

            buttonGrid[1, 0] = B10;
            buttonGrid[1, 1] = B11;
            buttonGrid[1, 2] = B12;
            buttonGrid[1, 3] = B13;
            buttonGrid[1, 4] = B14;
            buttonGrid[1, 5] = B15;
            buttonGrid[1, 6] = B16;

            buttonGrid[2, 0] = B20;
            buttonGrid[2, 1] = B21;
            buttonGrid[2, 2] = B22;
            buttonGrid[2, 3] = B23;
            buttonGrid[2, 4] = B24;
            buttonGrid[2, 5] = B25;
            buttonGrid[2, 6] = B26;

            buttonGrid[3, 0] = B30;
            buttonGrid[3, 1] = B31;
            buttonGrid[3, 2] = B32;
            buttonGrid[3, 3] = B33;
            buttonGrid[3, 4] = B34;
            buttonGrid[3, 5] = B35;
            buttonGrid[3, 6] = B36;

            buttonGrid[4, 0] = B40;
            buttonGrid[4, 1] = B41;
            buttonGrid[4, 2] = B42;
            buttonGrid[4, 3] = B43;
            buttonGrid[4, 4] = B44;
            buttonGrid[4, 5] = B45;
            buttonGrid[4, 6] = B46;

            buttonGrid[5, 0] = B50;
            buttonGrid[5, 1] = B51;
            buttonGrid[5, 2] = B52;
            buttonGrid[5, 3] = B53;
            buttonGrid[5, 4] = B54;
            buttonGrid[5, 5] = B55;
            buttonGrid[5, 6] = B56;

            for (int x = 0; x < _height; x++)
            {
                for (int y = 0; y < _width; y++)
                {
                    buttonGrid[x, y].Tag = (x * 10) + y;
                    buttonGrid[x, y].Click += Button_Click;
                }
            }
        }

        private void loadMonth()
        {
            TextBoxMonthYear.Text = CultureInfo.CurrentCulture.DateTimeFormat.GetMonthName(_datetime.Month) + " " + _datetime.Year;
            int daysInMonth = DateTime.DaysInMonth(_datetime.Year, _datetime.Month);
            DateTime firstOfCurrentMonth = new DateTime(_datetime.Year, _datetime.Month, 1);
            int dayOnFirstOfCurrentMonth = (int)firstOfCurrentMonth.DayOfWeek;

            int previousMonthYearIndex = _datetime.Year;
            int previousMonthIndex = 12;

            if (_datetime.Month > 1)
                previousMonthIndex = _datetime.Month - 1;
            else
                previousMonthYearIndex--;

            int daysInPreviousMonth = DateTime.DaysInMonth(previousMonthYearIndex, previousMonthIndex);

            int dayCounter = 1;
            int previousMonthOfset = 0;
            int nextMonthDayCounter = 1;

            for (int x = 0; x < _height; x++)
            {
                for (int y = 0; y < _width; y++)
                {
                    buttonGrid[x, y].Background = new SolidColorBrush(Colors.Transparent);

                    if (x == 0 && y < dayOnFirstOfCurrentMonth)
                    {
                        buttonGrid[x, y].Content = "" + (daysInPreviousMonth - (dayOnFirstOfCurrentMonth - previousMonthOfset) + 1);
                        buttonGrid[x, y].Foreground = new SolidColorBrush(Colors.Gray);
                        buttonGrid[x, y].BorderBrush = new SolidColorBrush(Colors.Gray);
                        previousMonthOfset++;
                    }
                    else if ((dayCounter - previousMonthOfset) >= daysInMonth + 1)
                    {
                        buttonGrid[x, y].Content = "" + nextMonthDayCounter;
                        buttonGrid[x, y].Foreground = new SolidColorBrush(Colors.Gray);
                        buttonGrid[x, y].BorderBrush = new SolidColorBrush(Colors.Gray);
                        nextMonthDayCounter++;
                    }
                    else
                    {
                        buttonGrid[x, y].Content = "" + (dayCounter - previousMonthOfset);
                        buttonGrid[x, y].Foreground = new SolidColorBrush(Colors.White);
                        buttonGrid[x, y].BorderBrush = new SolidColorBrush(Colors.White);
                    }

                    if ((dayCounter - dayOnFirstOfCurrentMonth) == DateTime.Now.Day && _datetime.Month == DateTime.Now.Month)
                    {
                        buttonGrid[x, y].Background = new SolidColorBrush(Colors.Gray);
                        buttonGrid[x, y].BorderBrush = new SolidColorBrush(Colors.White);
                    }

                    if ((dayCounter - dayOnFirstOfCurrentMonth) == _datetime.Day)
                    {
                        buttonGrid[x, y].Background = new SolidColorBrush(Colors.SteelBlue);
                        buttonGrid[x, y].BorderBrush = new SolidColorBrush(Colors.OrangeRed);
                    }

                    dayCounter++;
                }
            }
        }

        private async void Button_Click(object sender, RoutedEventArgs e)
        {
            Button senderButton = (Button)sender;
            int buttonTag = (int)senderButton.Tag;

            int xIndex = buttonTag / 10;
            int yIndex = buttonTag % 10;

            int daysInMonth = DateTime.DaysInMonth(_datetime.Year, _datetime.Month);
            DateTime firstOfCurrentMonth = new DateTime(_datetime.Year, _datetime.Month, 1);
            int dayOnFirstOfCurrentMonth = (int)firstOfCurrentMonth.DayOfWeek;

            int previousMonthYearIndex = _datetime.Year;
            int previousMonthIndex = 12;

            if (_datetime.Month > 1)
                previousMonthIndex = _datetime.Month - 1;
            else
                previousMonthYearIndex--;

            int daysInPreviousMonth = DateTime.DaysInMonth(previousMonthYearIndex, previousMonthIndex);


            int nextMonthYearIndex = _datetime.Year;
            int nextMonthIndex = 1;

            if (_datetime.Month < 12)
                nextMonthIndex = _datetime.Month + 1;
            else
                nextMonthYearIndex++;


            int selectedDay = yIndex + 1 + (xIndex * _width) - dayOnFirstOfCurrentMonth;


            int yearToSelect = _datetime.Year;
            int monthToSelect = _datetime.Month;
            int dayToSelect = selectedDay;

            if (selectedDay <= 0)
            {
                Debug.WriteLine("load a date in previous month");
                _datetime = new DateTime(previousMonthYearIndex, previousMonthIndex, daysInPreviousMonth + selectedDay);
            }
            else if (selectedDay > daysInMonth)
            {
                Debug.WriteLine("load a date in next month");
                _datetime = new DateTime(nextMonthYearIndex, nextMonthIndex, selectedDay - daysInMonth);
            }
            else
            {
                Debug.WriteLine("selected day: " + selectedDay);
                _datetime = new DateTime(_datetime.Year, _datetime.Month, selectedDay);
            }


            loadMonth();

        }

        private void setupListViews()
        {
            ListViewHours.Items.Clear();
            ListViewMinutes.Items.Clear();

            for (int x = 1; x <= 24; x++)
            {
                ListViewHours.Items.Add(x.ToString(" 00"));
            }
            for (int x = 1; x <= 60; x++)
            {
                ListViewMinutes.Items.Add(x.ToString(" 00"));
            }

            ListViewHours.SelectedIndex = _datetime.Hour;
            ListViewMinutes.SelectedIndex = _datetime.Minute;

            ListViewHours.ScrollIntoView(ListViewHours.SelectedIndex);
            ListViewMinutes.ScrollIntoView(ListViewMinutes.SelectedIndex);

        }

        private void ListViewHours_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Debug.WriteLine("hour chosen: " + ListViewHours.SelectedValue);
            _datetime = new DateTime(_datetime.Year, _datetime.Month, _datetime.Day, (ListViewHours.SelectedIndex + 1), _datetime.Minute, _datetime.Second);
            ListViewHours.ScrollIntoView(ListViewHours.SelectedIndex);
            ListViewMinutes.ScrollIntoView(ListViewMinutes.SelectedIndex);
        }

        private void ListViewMinutes_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Debug.WriteLine("minute chosen: " + ListViewMinutes.SelectedValue);
            _datetime = new DateTime(_datetime.Year, _datetime.Month, _datetime.Day, _datetime.Hour, (ListViewMinutes.SelectedIndex + 1), _datetime.Second);
            ListViewHours.ScrollIntoView(ListViewHours.SelectedIndex);
            ListViewMinutes.ScrollIntoView(ListViewMinutes.SelectedIndex);
        }

        private void ButttonPreviousMonth_Click(object sender, RoutedEventArgs e)
        {
            _datetime = _datetime.AddMonths(-1);
            loadMonth();
        }

        private void ButtonNextMonth_Click(object sender, RoutedEventArgs e)
        {
            _datetime = _datetime.AddMonths(1);
            loadMonth();
        }
    }
}
